package com.freecloud.spring.formework.beans.support;

import com.freecloud.spring.formework.beans.config.FCBeanDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * 加载配置，扫描
 * @Author: maomao
 * @Date: 2019-12-10 10:01
 */
public class FCBeanDefinitionReader {

    private Properties config = new Properties();

    private List<String> registyBeanClasses = new ArrayList<>();

    /**
     * 固定配置文件Key，相当于XMl规范
     */
    private final String SCAN_PACKAGE = "scanPackage";


    public FCBeanDefinitionReader(String... locations){
        //通过URL定位，找到对应配置文件
        try(InputStream fis = this.getClass().getClassLoader().getResourceAsStream(locations[0].replace("classpath:",""))) {
            config.load(fis);
        } catch (IOException e) {
            e.printStackTrace();
        }

        doScanner(config.getProperty(SCAN_PACKAGE));
    }

    private void doScanner(String scanPackage) {

        URL url = this.getClass().getResource("/" + scanPackage.replaceAll("\\.","/"));
        //有路径转换问题
        //URL url = this.getClass().getClassLoader().getResource(scanPackage.replaceAll("\\.","/"));
        File classPath = new File(url.getFile());

        for(File file: classPath.listFiles()){
            if(file.isDirectory()){
                doScanner(scanPackage + "." + file.getName());
            }else {
                if(!file.getName().endsWith(".class")){
                    continue;
                }
                String className = (scanPackage + "." + file.getName().replace(".class",""));
                registyBeanClasses.add(className);
            }
        }
    }

    /**
     * 把配置文件中扫描到的所有配置信息转换到FCBeanDefinition中，便于后边直接使用
     * @return
     */
    public List<FCBeanDefinition> loadBeanDefinitions(){

        List<FCBeanDefinition> result = new ArrayList<>();
        FCBeanDefinition beanDefinition;
        try{
            Class<?> beanClass;
            for (String className: registyBeanClasses) {
                beanClass = Class.forName(className);
                if(beanClass.isInterface()){
                    continue;
                }
                //beanName有三种情况:
                //1、默认是类名首字母小写
                //2、自定义名字
                //3、接口注入
                beanDefinition = doCreateBeanDefinition(toLowerFirstCase(beanClass.getSimpleName()), beanClass.getName());
                result.add(beanDefinition);

                Class<?> [] interfaces = beanClass.getInterfaces();
                for (Class<?> i : interfaces) {
                    //如果是多个实现类，只能覆盖
                    //为什么？因为Spring没那么智能，就是这么傻
                    //这个时候，可以自定义名字
                    result.add(doCreateBeanDefinition(i.getName(),beanClass.getName()));
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return result;
    }

    private FCBeanDefinition doCreateBeanDefinition(String factoryBeanName,String beanClassName){
        FCBeanDefinition beanDefinition = new FCBeanDefinition();
        beanDefinition.setBeanClassName(beanClassName);
        beanDefinition.setFactoryBeanName(factoryBeanName);
        return beanDefinition;
    }

    /**
     * 转换首字母为小写
     * 如类名本身为小写时，会出现问题
     * @param simpleName
     * @return
     */
    private String toLowerFirstCase(String simpleName){
        char[] chars = simpleName.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }

    public Properties getConfig() {
        return config;
    }
}
